﻿using System;
using System.IO;
using System.Xml;
using System.Xml.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

namespace comm
{
    public static class JsonSerializer
    {
        public static string Serialize(object obj, bool isCompact = true, bool outputType = false)
        {
            using (var sw = new StringWriter())
            {
                var s = new json.Serializer(obj.GetType());
                s.Config.OutputTypeInformation = outputType;
                s.Config.IsCompact = isCompact;
                s.Serialize(obj, sw);
                return sw.ToString();
            }
        }
        public static object Deserialize(Type type, string json)
        {
            using (var sr = new StringReader(json))
            {
                var s = new json.Serializer(type);
                return s.Deserialize(json);
            }
        }
        public static T Deserialize<T>(string json)
        {
            return (T)Deserialize(typeof(T), json);
        }
    }

    public static class BinarySerializer
    {
        public static string SerializeToBase64(object obj)
        {
            return Convert.ToBase64String(Serialize(obj));
        }
        public static object DeserializeFromBase64(string base64)
        {
            return Deserialize(Convert.FromBase64String(base64));
        }
        public static T DeserializeFromBase64<T>(string base64)
        {
            return Deserialize<T>(Convert.FromBase64String(base64));
        }
        public static byte[] Serialize(object obj)
        {
            using (var ms = new MemoryStream())
            {
                var bf = new BinaryFormatter();
                bf.Serialize(ms, obj);
                return ms.GetBuffer();
            }
        }
        public static object Deserialize(byte[] bytes)
        {
            using (var ms = new MemoryStream(bytes))
            {
                var bf = new BinaryFormatter();
                return bf.Deserialize(ms);
            }
        }
        public static T Deserialize<T>(byte[] bytes)
        {
            return (T)Deserialize(bytes);
        }
    }

    public static class XMLSerializer
    {
        public static string Serialize(object obj)
        {
            var s = new XmlSerializer(obj.GetType());
            using (var sw = new StringWriter())
            {
                using (var xr = XmlWriter.Create(sw, new XmlWriterSettings
                {
                    Indent = true,
                    IndentChars = "    ",
                    OmitXmlDeclaration = true,
                }))
                {
                    s.Serialize(xr, obj);
                    var xml = sw.ToString();
                    xml = xml.Replace(" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"", "");
                    return xml;
                }
            }
        }
        public static object Deserialize(Type type, string xml)
        {
            using (var sr = new StringReader(xml))
            {
                var s = new XmlSerializer(type);
                return s.Deserialize(sr);
            }
        }
        public static T Deserialize<T>(string xml)
        {
            return (T)Deserialize(typeof(T), xml);
        }
    }
}
